#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <pthread.h>

#include "log.h"
#include "timestamp.h"

#define MAX_LOG_BUFFER      500

const char* log_level_str[LOG_MAX] = {
    "DEBUG",
    "INFO ",
    "WARN ",
    "ERROR"
};

#ifdef NDEBUG
static LOG_LEVEL    outputLevel = LOG_INFO;
#else
static LOG_LEVEL    outputLevel = LOG_DEBUG;
#endif

gpointer log_task(gpointer data);

static GThread*     log_task_h = NULL;

static GAsyncQueue* log_queue = NULL;

void logInit()
{
    log_queue = g_async_queue_new();

    log_task_h = g_thread_new("Log thread", log_task, NULL);
}

gpointer log_task(gpointer data) {
    char*       buffer;
    guint64     timeout;

    timeout = 500 * 1000;      // microseconds

    while(1) {
        buffer = (char*)g_async_queue_timeout_pop(log_queue, timeout );

        if (!buffer) {
            continue;
        }

        // TODO
        printf("%s\r\n", buffer);
        free(buffer);
        buffer = NULL;
    }
    return 0;
}

void log_print(LOG_LEVEL l, const char *format, ...)
{
    char*       buffer;
    va_list     ap;
    int         timestamp_l;

    if (l < outputLevel) {
        return;
    }

    buffer = malloc(MAX_LOG_BUFFER);

    // TIMESTAMP & Level
    timestamp_l = getTimestamp(buffer, MAX_LOG_BUFFER);
    timestamp_l += snprintf(buffer + timestamp_l, MAX_LOG_BUFFER - timestamp_l, " %s ", log_level_str[l]);

    va_start(ap, format);
    vsnprintf(buffer + timestamp_l, MAX_LOG_BUFFER - timestamp_l, format, ap);
    va_end(ap);

    g_async_queue_push(log_queue, buffer);
}

void set_log_level(LOG_LEVEL l)
{
    outputLevel = l;
}